package com.project.collectAPI.comm;

/**
 * Created by lijinquan on 2017/3/28.
 */

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemWriter;

import java.io.StringWriter;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

/** 生成RSA2的公钥和私钥方法 */
class RSA2 {
    public static final String KEY_ALGORITHM = "RSA";
    public static final String CIPHER_ALGORITHM = "RSA/ECB/PKCS1Padding";
    public static final String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArn3DKEeW31eRok+navMVf9+Z+D43BeLv6/BwcfVoThdf1pxA15/4jY1+BJIvEbb1gMPP7Vi7LRfowJTCxePNAdbh8vZaWsogxYtyWLZvEvw1nNrGB3JhRM+VvQ+zXT2RpUCJTId7ngEgF4kcwzJxM0f9Dfh8GWlxI9FlQl6MMFsrI3EyLdeM7k6Y4ROIm5Hperq1POxSSLOxpjPjcxFbYWEY3FooNFEj8LIIHkELqlgqzDpYF1PagFW3odWCUV0Z1KysPwpQLvyX3adG0JJK3fzZl22Ap3QKDBuNWiKclN958acAnEjCEKQHTZWgQR5qHs1kPxVHOxhFmvwwa6I0QwIDAQAB";
    public static final String PRIVATE_KEY = "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCufcMoR5bfV5GiT6dq8xV/35n4PjcF4u/r8HBx9WhOF1/WnEDXn/iNjX4Eki8RtvWAw8/tWLstF+jAlMLF480B1uHy9lpayiDFi3JYtm8S/DWc2sYHcmFEz5W9D7NdPZGlQIlMh3ueASAXiRzDMnEzR/0N+HwZaXEj0WVCXowwWysjcTIt14zuTpjhE4ibkel6urU87FJIs7GmM+NzEVthYRjcWig0USPwsggeQQuqWCrMOlgXU9qAVbeh1YJRXRnUrKw/ClAu/Jfdp0bQkkrd/NmXbYCndAoMG41aIpyU33nxpwCcSMIQpAdNlaBBHmoezWQ/FUc7GEWa/DBrojRDAgMBAAECggEAcEutikGwXiIcLqo2o4S3hGkhzPo1LQukvmIp6501OHSgkBxVOq/QJUE3JbfypOLrUqgyK5ycMWQevbm/M93sNM/W8CcNdTp6Jsgcme0mxMAdvMmrAmXhJYi25Eqzc0FJd2F2OxNCQiiVP7BVG2ZeJdOhjxkovK34S0XadgElFYSyHPWQ4+9geL4KyOUnrv8ATE5Tfl2XgkUpYoe5J8Sv7+GFBiQQE1nhcayYV9g80H7n7qScp8p07+Z7Z5745DV1FBfI5QspFsp+d+/LxvS1iIZNrS6oEyHhW5ke1O/RYngdWkkh1vsqAkj6DfUnDZVJNNj+5sLaTnaPZlbfWotrgQKBgQD+cbaV6jIKycn7nveL1tdkalZ2f9+R7LSAeAmBxCFHQmoyTxj9nkGPr7UPELWYm5U9D81rJLlT+GT7BDRdUfc9OyUI3Qy4pmglmoPlUj1mMgnrmwi5cD4samYcu4wWgDx3rK4HrVwWLT8aj9FgsZakzpz5dIqpt6OVvi09DKZFwQKBgQCvjuWp1TzgixeWfzy6y+L6dJd/nORpyFed81NcGKXfa7TZ5Hy25uvOSFHxIRwahvkE0+fbz4IXOTPEq2fCRHl9P4SDLZ8JuOi1t8PdRgbJMWKj9qZVw0xksmdKWyNTZCJVSzo4cH/ij57y2pP4W+4c0Ah69lRYlzH1PUWXD6YjAwKBgQDGEi1JbINCJK1og+o+YKNR1vmxy391sCcfLtJvwwcI2umiejKBE9YDjYtLy/0hbFPzsb5+Hptqg53QTgiZcLofX1BIIxPJFjlStILiXG/Rgzh3wTs8Z+TuXHFbAqBdz7vCiZj7/vcFiHlsKvKZ7ATSDMjj49YhogPlCKNct+EjwQKBgQCUeHRQki8+80MKmybAD2gxSmNJoGUn9S/sO/m2vH2jmtJDKFI02Mx6E32BQPAkmxuEcrX2luK9Qzo9zHwetoxMWWh3DCEhNslPzU8PFobspiB27ES16Un1K0/heXxBrUDAA7QEQVhWQgI5/pL/irewlFtnqmWg2pV8gsoUvD5UAwKBgQDh+K7dleffF+nC3qiaCerlykoaRFsiH3z6q2J8Zuz0cERHP9t/9ukL2LKVP+M1K9UE2boc7ssqJ2At8yxIURSFCldxzpZWyOH/Zb/jydgjeaUcF39dK11C78cA9ZgWLGHFzS2wojSRcF8Edu2RTvjwla9d01Skzw9r5gSLbHfzGw==";
    public static final int KEY_SIZE = 2048;
    /**
     * 生成密钥对
     *
     * @return
     */
    public static Map<String, byte[]> generateKeyBytes() {

        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator
                    .getInstance(KEY_ALGORITHM);
            keyPairGenerator.initialize(KEY_SIZE);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
            Map<String, byte[]> keyMap = new HashMap<String, byte[]>();
            keyMap.put(PUBLIC_KEY, publicKey.getEncoded());
            keyMap.put(PRIVATE_KEY, privateKey.getEncoded());
//            System.out.println("privateKey="+ Base64.encode(privateKey.getEncoded()));
//            System.out.println("publicKey="+Base64.encode(publicKey.getEncoded()));


            return keyMap;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }


    /***
     *
     * @param privateKey
     * @return
     * @throws Exception
     */
    public static String privatePem(String privateKey) throws Exception{
        byte[] privBytes = Base64.decodeBase64(privateKey);

        PrivateKeyInfo pkInfo = PrivateKeyInfo.getInstance(privBytes);
        ASN1Encodable encodable = pkInfo.parsePrivateKey();
        ASN1Primitive primitive = encodable.toASN1Primitive();
        byte[] privateKeyPKCS1 = primitive.getEncoded();

        return pkcs1ToPem(privateKeyPKCS1,false);
    }



    public static String pkcs1ToPem(byte[] pcks1KeyBytes,boolean isPublic) throws Exception{
        String type;
        if(isPublic){
            type = "RSA PUBLIC KEY";
        }else{
            type = "RSA PRIVATE KEY";
        }

        PemObject pemObject = new PemObject(type, pcks1KeyBytes);
        StringWriter stringWriter = new StringWriter();
        PemWriter pemWriter = new PemWriter(stringWriter);
        pemWriter.writeObject(pemObject);
        pemWriter.close();
        String pemString = stringWriter.toString();

        return pemString;
    }

    /**
     * 格式化java生成的key，一行长的，不适合pem中的-----BEGIN PUBLIC KEY-----，pem已经有换行了
     * @param key
     */
    public static void formatKey(String key){
        if(key==null) return;

        key = key.replace("\n","");

        int count = (key.length()-1)/64+1;
        for(int i=0;i<count;i++){
            if(i+1==count){
                //循环的最后一次
                System.out.println(key.substring(i*64));
            }else{
                System.out.println(key.substring(i*64,i*64+64));
            }
        }
    }

    /**
     * 从pem格式(-----BEGIN PUBLIC KEY-----)的key获取一行key
     * @param pem
     * @return
     */
    public static String pemToKey(String pem){
        if(pem==null) return "";
        if(pem.indexOf("KEY-----")>0){
            pem = pem.substring(pem.indexOf("KEY-----")+"KEY-----".length());
        }
        if(pem.indexOf("-----END")>0){
            pem = pem.substring(0,pem.indexOf("-----END"));
        }
        return pem.replace("\n","");
    }



    /**
     * 还原公钥
     *
     * @param keyBytes
     * @return
     */
    public static PublicKey restorePublicKey(byte[] keyBytes) {
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
        try {
            KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
            PublicKey publicKey = factory.generatePublic(x509EncodedKeySpec);
            return publicKey;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 还原私钥
     *
     * @param keyBytes
     * @return
     */
    public static PrivateKey restorePrivateKey(byte[] keyBytes) {
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(
                keyBytes);
        try {
            KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
            PrivateKey privateKey = factory
                    .generatePrivate(pkcs8EncodedKeySpec);
            return privateKey;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
        return null;
    }


}